//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Resource Application Block
//===============================================================================

using System.Diagnostics;
using System.Threading;
using Microsoft.Practices.EnterpriseLibrary.Common.Instrumentation;
using EntLibContrib.Resource.Instrumentation;
#if !NUNIT
using Microsoft.VisualStudio.TestTools.UnitTesting;
#else
using NUnit.Framework;
using TestClass = NUnit.Framework.TestFixtureAttribute;
using TestInitialize = NUnit.Framework.SetUpAttribute;
using TestCleanup = NUnit.Framework.TearDownAttribute;
using TestMethod = NUnit.Framework.TestAttribute;
#endif

namespace EntLibContrib.Resource.Instrumentation.Tests
{
	[TestClass]
	public class ResourcePerformanceCountersFixture
	{
		private const string instanceName = "test";
		private string formattedInstanceName;

		private NoPrefixNameFormatter formatter;
		private PerformanceCounter resourceEntriesCounter;
		private PerformanceCounter resourceAccessCounter;
		private PerformanceCounter resourceAccessRateCounter;

		[TestInitialize]
		public void SetUp ()
		{
			formatter = new NoPrefixNameFormatter();
			formattedInstanceName = formatter.CreateName(instanceName);

			resourceEntriesCounter = CreatePerformanceCounter("Total Resource Entries", formattedInstanceName);
			resourceEntriesCounter.RawValue = 0;
			resourceAccessCounter = CreatePerformanceCounter("Total Resource Accesses", formattedInstanceName);
			resourceAccessCounter.RawValue = 0;
			resourceAccessRateCounter = CreatePerformanceCounter("Resource Access Rate", formattedInstanceName);
			resourceAccessRateCounter.RawValue = 0;
		}

		[TestCleanup]
		public void TearDown ()
		{
			resourceEntriesCounter.Dispose();
			resourceAccessCounter.Dispose();
			resourceAccessRateCounter.Dispose();
		}

		private static PerformanceCounter CreatePerformanceCounter (string name, string formattedInstanceName)
		{
			return new PerformanceCounter(ResourceInstrumentationListener.ResourceCountersCategoryName, name, formattedInstanceName, false);
		}

		[TestMethod]
		public void ResourceInitializationWithPerformanceCountersDisabledDoesNotUpdateCounters ()
		{
			ResourceInstrumentationListener listener = new ResourceInstrumentationListener(instanceName, false, false, false, formatter);

			ResourceInitializedEventArgs args = new ResourceInitializedEventArgs(100L);

			listener.ResourceInitialized(null, args);

			Assert.AreEqual(0L, resourceEntriesCounter.RawValue);
		}

		[TestMethod]
		public void ResourceInitializationWithPerformanceCountersEnabledDoesUpdateCounters ()
		{
			ResourceInstrumentationListener listener = new ResourceInstrumentationListener(instanceName, true, false, false, formatter);

			ResourceInitializedEventArgs args = new ResourceInitializedEventArgs(100L);

			listener.ResourceInitialized(null, args);

			Assert.AreEqual(100L, resourceEntriesCounter.RawValue);
		}

		[TestMethod]
		public void ResourceAccessWithPerformanceCountersDisabledDoesNotUpdateCounters ()
		{
			ResourceInstrumentationListener listener = new ResourceInstrumentationListener(instanceName, false, false, false, formatter);

			ResourceAccessedEventArgs args = new ResourceAccessedEventArgs("key");

			listener.ResourceAccessed(null, args);

			Assert.AreEqual(0L, resourceAccessCounter.RawValue);
			Assert.AreEqual(0L, resourceAccessRateCounter.RawValue);
		}

		[TestMethod]
		public void ResourceAccessWithPerformanceCountersEnabledDoesUpdateCounters ()
		{
			ResourceInstrumentationListener listener = new ResourceInstrumentationListener(instanceName, true, false, false, formatter);

			ResourceAccessedEventArgs args = new ResourceAccessedEventArgs("key");

			listener.ResourceAccessed(null, args);

			Assert.AreEqual(1L, resourceAccessCounter.RawValue);
			Assert.AreEqual(1L, resourceAccessRateCounter.RawValue);
		}

		[TestMethod]
		public void MultipleResourceAccessWithPerformanceCountersEnabledDoesUpdateCounters ()
		{
			ResourceInstrumentationListener listener = new ResourceInstrumentationListener(instanceName, true, false, false, formatter);

			ResourceAccessedEventArgs accessArgs = new ResourceAccessedEventArgs("key");

			for ( int i = 0; i < 10; i++ )
			{
				listener.ResourceAccessed(null, accessArgs);
			}
			resourceAccessRateCounter.NextValue();

			Thread.Sleep(1000);

			for ( int i = 0; i < 10; i++ )
			{
				listener.ResourceAccessed(null, accessArgs);
			}
			resourceAccessRateCounter.NextValue();

			Assert.AreEqual(20L, resourceAccessCounter.RawValue);
			Assert.AreEqual(20L, resourceAccessRateCounter.RawValue);
		}
	}
}